package com.liuxinlong.modules.material.service.impl;

import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.common.uploadSMBJ.SMBJConfig;
import com.liuxinlong.common.uploadSMBJ.SMBJInterface;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.ChangeCategoryTypeEnum;
import com.liuxinlong.enums.MaterialResumeTypeEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.MaterialDao;
import com.liuxinlong.modules.dao.MaterialReplaceDao;
import com.liuxinlong.modules.dao.MaterialResumeDao;
import com.liuxinlong.modules.dao.MocDetailDao;
import com.liuxinlong.modules.dao.ShareFileDao;
import com.liuxinlong.modules.entity.EcnContent;
import com.liuxinlong.modules.entity.MaterialReplace;
import com.liuxinlong.modules.entity.MaterialResume;
import com.liuxinlong.modules.entity.ShareFile;
import com.liuxinlong.modules.material.dto.MaterialInfoDto;
import com.liuxinlong.modules.material.dto.MaterialResumeChangeDto;
import com.liuxinlong.modules.material.service.MaterialResumeService;
import com.liuxinlong.modules.out.service.DocumentService;
import com.liuxinlong.modules.out.service.OutEcnService;
import com.liuxinlong.modules.sync.service.SyncService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物料履历信息服务层接口实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-01-17
 */
@Service
@Slf4j
public class MaterialResumeServiceImpl implements MaterialResumeService {
    @Autowired
    private MaterialDao materialDao;

    @Autowired
    private MaterialResumeDao materialResumeDao;

    @Autowired
    private SyncService syncService;

    @Autowired
    private OutEcnService outEcnService;

    @Autowired
    private MaterialReplaceDao materialReplaceDao;

    @Autowired
    private MocDetailDao mocDetailDao;

    @Autowired
    private DocumentService documentService;

    @Autowired
    private ShareFileDao shareFileDao;

    @Autowired
    private SMBJInterface smbjInterface;

    @Autowired
    private SMBJConfig smbjConfig;

    @Override
    public List<Map<String, Object>> pageResumeInfo(Map<String, Object> queryParam) {
        List<MaterialResume> originList = materialResumeDao.pageResumeList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (MaterialResume resume : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(resume);
            map.put("sort", sort);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getResumeCount(Map<String, Object> queryParam) {
        return materialResumeDao.getResumeCount(queryParam);
    }

    @Override
    public void addResumeInfo(MaterialResume materialResume) {
        materialResume.setId(SnowFlake.nextIdStr());
        materialResumeDao.addResume(materialResume);
    }

    @Override
    public void updateResumeInfo(MaterialResume materialResume) {
        materialResumeDao.updateResume(materialResume);
    }

    @Override
    public void deleteResumeInfo(String id) {
        materialResumeDao.deleteResume(id);
    }


    @Override
    public Map<String, Object> queryResumeInfo(String material, String region, String checkStartTime) {
        // 物料基本信息
        Map<String, Object> materialInfo = syncService.getOneMaterial(material, region);
        if (ObjectUtils.isEmpty(materialInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "物料不存在");
        }
        // 物料新建时间
        Date addTime = (Date) materialInfo.get("pt_added");
        Map<String, Object> dataMap = new HashMap<>();
        String materialAddTime = TimeUtils.formatTime(addTime, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        String childStartTime = materialAddTime.compareTo(checkStartTime) > 1 ? materialAddTime : checkStartTime;
        materialInfo.put("addTime", materialAddTime);
        dataMap.put("baseInfo", materialInfo);

        // 物料履历列表数据
        List<MaterialResume> materialResumes = materialResumeDao.getMaterialResume(material, region);
        boolean existAdd = false;
        Map<String, String> resumesMap = new HashMap<>();
        // 履历树
        List<MaterialResume> resultList = new ArrayList<>();
        MaterialResume mrReplace = new MaterialResume();
        Map<String, String> existMap = new HashMap<>();
        int countEcn = 0;
        for (MaterialResume resume : materialResumes) {
            if (resume.getOperateType() == MaterialResumeTypeEnum.ECN_CHANGE.getValue()) {
                countEcn++;
                if (StringUtils.isNotEmpty(resume.getOperateTime())) {
                    String key = resume.getSourceId() + resume.getOperateType() + resume.getOperateTime();
                    if (existMap.containsKey(key)) {
                        continue;
                    }
                    existMap.put(key, key);
                    // 新增BOM不展示
                    if (StringUtils.equals(resume.getContent(), ChangeCategoryTypeEnum.NEW_BOM.getName())) {
                        continue;
                    }
                    resultList.add(resume);
                }
            }
            resumesMap.put(resume.getSourceId(), resume.getId());
            if (resume.getOperateType() == MaterialResumeTypeEnum.ADD_CHANGE.getValue()) {
                existAdd = true;
                resultList.add(resume);
                continue;
            }
            if (resume.getOperateType() == MaterialResumeTypeEnum.REPLACE_CHANGE.getValue()) {
                mrReplace = resume;
                continue;
            }
            if (resume.getOperateType() == MaterialResumeTypeEnum.STATUS_CHANGE.getValue()) {
//                statusChangeMap.put(resume.getId(), resume.getSourceId());
                resultList.add(resume);
            }
            if (resume.getOperateType() == MaterialResumeTypeEnum.PARAM_CHANGE.getValue()) {
                resultList.add(resume);
            }
        }

        // ecn变更信息
        List<EcnContent> ecnContentList = outEcnService.getEcnContentByMaterial(material, region);
        if (ecnContentList.size() > countEcn) {
            List<MaterialResume> mrList = new ArrayList<>();
            for (EcnContent content : ecnContentList) {
                String category = content.getChangingCategory();
//                if (StringUtils.equals(ChangeCategoryTypeEnum.NEW_MATERIAL.getCategory(), content.getChangingCategory())) {
//                    existAdd = true;
//                }
                String contentId = content.getEcnNo();
                if (resumesMap.containsKey(contentId)) {
                    continue;
                }

//                if (!StringUtils.equals(category,ChangeCategoryTypeEnum.ADD_BOM.getCategory()) &&
//                        !StringUtils.equals(category,ChangeCategoryTypeEnum.EXP_BOM.getCategory()) &&
//                        !StringUtils.equals(category,ChangeCategoryTypeEnum.REV_DRAWING.getCategory()) ) {
//                    continue;
//                }
//                if (StringUtils.equals(category,ChangeCategoryTypeEnum.NEW_BOM.getCategory())) {
//                    continue;
//                }
                MaterialResume mr = new MaterialResume();
                mr.setId(SnowFlake.nextIdStr());
                mr.setSourceId(contentId);
                mr.setMaterialNo(material);
                mr.setRegion(region);
                mr.setOperateType(MaterialResumeTypeEnum.ECN_CHANGE.getValue());
                mr.setContent(ChangeCategoryTypeEnum.getNameByValue(ChangeCategoryTypeEnum.getValueByCategory(content.getChangingCategory())));
                mr.setSourceId(contentId);
                mr.setOperateUser("");
                if (StringUtils.equals(category, ChangeCategoryTypeEnum.EXP_BOM.getCategory())
                        || StringUtils.equals(category, ChangeCategoryTypeEnum.EXP_WORK_HOUR.getCategory())
                        || StringUtils.equals(category, ChangeCategoryTypeEnum.EXP_IMAGINARY.getCategory())) {
                    mr.setOperateTime(StringUtils.isNotEmpty(content.getEndTime()) ?
                            TimeUtils.formatTime(content.getEndTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS) : null);
                } else {
                    mr.setOperateTime(StringUtils.isNotEmpty(content.getStartTime()) ?
                            TimeUtils.formatTime(content.getStartTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS) : null);
                }
                log.info("operateTime", mr.getOperateTime());
                if (StringUtils.equals(mr.getOperateTime(), "1900-01-01 00:00:00")) {
                    mr.setOperateTime(null);
                }
                mrList.add(mr);
                materialResumes.add(mr);
                if (StringUtils.equals(content.getChangingCategory(), ChangeCategoryTypeEnum.NEW_BOM.getCategory())) {
                    continue;
                }
                if (StringUtils.isNotEmpty(mr.getOperateTime())) {
                    String key = mr.getSourceId() + mr.getOperateType() + mr.getOperateTime();
                    if (existMap.containsKey(key)) {
                        continue;
                    }
                    existMap.put(key, key);
                    resultList.add(mr);
                }
            }
            if (mrList.size() > 0) {
                materialResumeDao.batchAddResume(mrList);
            }
        }

        // 不存在新建记录需要手动添加
        if (!existAdd) {
            MaterialResume addResume = new MaterialResume();
            addResume.setId(SnowFlake.nextIdStr());
            addResume.setMaterialNo(material);
            addResume.setRegion(region);
            addResume.setOperateType(MaterialResumeTypeEnum.ADD_CHANGE.getValue());
            addResume.setContent(MaterialResumeTypeEnum.ADD_CHANGE.getName());
            addResume.setSourceId("");
            addResume.setOperateUser("");
            addResume.setOperateTime(TimeUtils.formatTime(addTime, TimeFormatConstants.YYYY_MM_DD_HH_MM_SS));
            materialResumeDao.addResume(addResume);
            resultList.add(0, addResume);
        }
        dataMap.put("resumeList", resultList.stream().sorted(
                Comparator.nullsLast(Comparator.comparing(MaterialResume::getOperateTime,
                        Comparator.nullsLast(String::compareTo)))).collect(Collectors.toList()));
        // 变更列表
        List<MaterialResumeChangeDto> recordList = new ArrayList<>(ecnContentList.size());
        Map<String, String> contentExistMap = new HashMap<>();

        for (EcnContent content : ecnContentList) {

            String key = content.getEcnNo() + content.getChangingCategory() + content.getStartTime() + content.getEndTime();
            if (contentExistMap.containsKey(key)) {
                continue;
            }
            contentExistMap.put(key, key);

            MaterialResumeChangeDto resumeChangeDto = new MaterialResumeChangeDto();
            resumeChangeDto.setRegion(content.getRegion());
            resumeChangeDto.setVersion(content.getRev());
            String startTime = StringUtils.isNotEmpty(content.getStartTime()) ?
                    TimeUtils.formatTime(content.getStartTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD) : null;
            resumeChangeDto.setStartTime(StringUtils.equals(startTime, "1900-01-01") ? null : startTime);
            String endTime = StringUtils.isNotEmpty(content.getEndTime()) ?
                    TimeUtils.formatTime(content.getEndTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD) : null;
            resumeChangeDto.setEndTime(StringUtils.equals(endTime, "1900-01-01") ? null : endTime);
            resumeChangeDto.setCompareTime(StringUtils.isNotEmpty(resumeChangeDto.getStartTime()) ? resumeChangeDto.getStartTime() : resumeChangeDto.getEndTime());
            resumeChangeDto.setChangingCategory(ChangeCategoryTypeEnum.getNameByValue(ChangeCategoryTypeEnum.getValueByCategory(content.getChangingCategory())));
            resumeChangeDto.setOperateTypeName(MaterialResumeTypeEnum.ECN_CHANGE.getName());
            resumeChangeDto.setEcnNo(content.getEcnNo());
            if (StringUtils.equals(content.getChangingCategory(), ChangeCategoryTypeEnum.EXP_BOM.getCategory()) && !StringUtils.isEmpty(mrReplace.getId())) {
                MaterialReplace mr = materialReplaceDao.selectById(mrReplace.getSourceId());
                resumeChangeDto.setReplace(mr.getReplaceMaterial());
            }
            if (StringUtils.equals(content.getChangingCategory(), ChangeCategoryTypeEnum.NEW_BOM.getCategory())) {
                continue;
            }
            recordList.add(resumeChangeDto);
        }

        List<MaterialResumeChangeDto> mocDetailList = mocDetailDao.getDetailsByMaterial(material, region);
        for (MaterialResumeChangeDto mocDetail : mocDetailList) {
            mocDetail.setStartTime(StringUtils.isNotEmpty(mocDetail.getStartTime()) ?
                    TimeUtils.formatTime(mocDetail.getStartTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS, TimeFormatConstants.YYYY_MM_DD)
                    : null);
            mocDetail.setEndTime(StringUtils.isNotEmpty(mocDetail.getEndTime()) ?
                    TimeUtils.formatTime(mocDetail.getEndTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS, TimeFormatConstants.YYYY_MM_DD)
                    : null);
            mocDetail.setOperateTypeName(MaterialResumeTypeEnum.getNameByValue(mocDetail.getOperateType()));
            recordList.add(mocDetail);
        }
        // 二次排序
        List<MaterialResumeChangeDto> changeList;
        List<MaterialResumeChangeDto> changeResultList = new ArrayList<>(recordList.size());
        if (recordList.size() > 0) {
            changeList = recordList.stream().sorted(
                    Comparator.nullsLast(Comparator.comparing(MaterialResumeChangeDto::getCompareTime,
                            Comparator.nullsLast(String::compareTo)))).collect(Collectors.toList());
            int sort = 1;
            for (MaterialResumeChangeDto mr : changeList) {
                mr.setSort(sort);

                changeResultList.add(mr);
                sort++;
            }
        }
        dataMap.put("changeList", changeResultList);
        List<String> firstChildList = getFirstChildMaterial(material, region, childStartTime);
        List<String> childList = getChildMaterial(firstChildList, region, new ArrayList<>(), childStartTime);
        // 子项履历树
        List<MaterialResumeChangeDto> childChangeList = queryChildChange(firstChildList, childList, material, region, childStartTime);
        dataMap.put("childChangeList", childChangeList);
        List<MaterialResume> childResumeList = queryChildResume(childChangeList);
        dataMap.put("childResumeList", childResumeList);
        return dataMap;

//        if (!replaceChangeMap.isEmpty() || !statusChangeMap.isEmpty() ) {
//            for (MaterialResume resume : resultList) {
//                if (replaceChangeMap.containsKey(resume.getId())) {
//                    Map<String, Object> map = new HashMap<>();
//                    MaterialReplace mr = materialReplaceDao.selectById(replaceChangeMap.get(resume.getId()));
//                    map.put("changingCategory",MaterialResumeTypeEnum.REPLACE_CHANGE.getName());
//                    map.put("operateTypeName",MaterialResumeTypeEnum.REPLACE_CHANGE.getName());
//                    map.put("sort",sort);
//                    map.put("replace",mr.getReplaceMaterial());
//                    map.put("region",mr.getRegion());
//                    map.put("ecnNo",mr.getEcn());
//                    changeList.add(map);
//                    sort ++;
//                    continue;
//                }
//                if (statusChangeMap.containsKey(resume.getId())) {
//                    Map<String, Object> map = new HashMap<>();
//                    map.put("changingCategory",MaterialResumeTypeEnum.REPLACE_CHANGE.getName());
//                    map.put("operateTypeName",MaterialResumeTypeEnum.REPLACE_CHANGE.getName());
//                    map.put("sort",sort);
//                    changeList.add(map);
//                    sort ++;
//                }
//            }
//        }
    }

    @Override
    public void queryDrawInfo(String id, HttpServletResponse response) {
        Map<String, Object> param = new HashMap<>();
        param.put("sourceNo", id);
        param.put("sourceType", 2);
        ShareFile shareFile = shareFileDao.getOneByNo(param);

        if (ObjectUtils.isEmpty(shareFile)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "文件不存在！");
        }
        smbjInterface.viewFile(shareFile, response);
    }

    @Override
    public void queryECNInfo(String id, HttpServletResponse response) {
        Map<String, Object> param = new HashMap<>();
        param.put("sourceNo", id);
        param.put("sourceType", 1);
        ShareFile shareFile = shareFileDao.getOneByNo(param);
        if (ObjectUtils.isEmpty(shareFile)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "文件不存在！");
        }
        smbjInterface.viewFile(shareFile, response);
    }

    @Override
    public void exportMaterialResume(String material, String region, String childStartTime, HttpServletResponse response) {
        Map<String, Object> menuMap = queryResumeInfo(material, region, childStartTime);
        List<ExcelData> excelDataList = new ArrayList<>();

        // 基本信息
        Map<String, Object> baseInfo = (Map<String, Object>) menuMap.get("baseInfo");
        ExcelData dataBase = new ExcelData();
        dataBase.setFileName("基本信息");
        String[] baseHead = {"物料号", "描述一", "描述二", "状态", "产品线", "图号", "版本", "加入时间", "域"};
        dataBase.setHead(baseHead);
        String[][] baseList = new String[1][baseHead.length];
        baseList[0][0] = baseInfo.containsKey("pt_part") ? (String) baseInfo.get("pt_part") : "";
        baseList[0][1] = baseInfo.containsKey("pt_desc1") ? (String) baseInfo.get("pt_desc1") : "";
        baseList[0][2] = baseInfo.containsKey("pt_desc2") ? (String) baseInfo.get("pt_desc2") : "";
        baseList[0][3] = baseInfo.containsKey("pt_status") ? (String) baseInfo.get("pt_status") : "";
        baseList[0][4] = baseInfo.containsKey("pt_prod_line") ? (String) baseInfo.get("pt_prod_line") : "";
        baseList[0][5] = baseInfo.containsKey("pt_draw") ? (String) baseInfo.get("pt_draw") : "";
        baseList[0][6] = baseInfo.containsKey("pt_rev") ? (String) baseInfo.get("pt_rev") : "";
        baseList[0][7] = baseInfo.containsKey("addTime") ? (String) baseInfo.get("addTime") : "";
        baseList[0][8] = baseInfo.containsKey("pt_domain") ? (String) baseInfo.get("pt_domain") : "";
        dataBase.setData(Arrays.asList(baseList));
        excelDataList.add(dataBase);

        // 变更列表
        List<MaterialResumeChangeDto> changeList = (List<MaterialResumeChangeDto>) menuMap.get("changeList");
        ExcelData changeData = new ExcelData();
        changeData.setFileName("变更列表");
        String[] changeHead = {"序号", "变更内容", "变更类型", "生效日期", "失效日期", "有替换", "版本", "ECN号", "域"};
        changeData.setHead(changeHead);
        String[][] changeDataList = new String[changeList.size()][changeHead.length];
        int changeIndex = 0;
        for (MaterialResumeChangeDto item : changeList) {
            changeDataList[changeIndex][0] = String.valueOf(changeIndex + 1);
            changeDataList[changeIndex][1] = item.getChangingCategory();
            changeDataList[changeIndex][2] = item.getOperateTypeName();
            changeDataList[changeIndex][3] = item.getStartTime();

            changeDataList[changeIndex][4] = item.getEndTime();
            changeDataList[changeIndex][5] = item.getReplace();
            changeDataList[changeIndex][6] = item.getVersion();
            changeDataList[changeIndex][7] = item.getEcnNo();
            changeDataList[changeIndex][8] = item.getRegion();
            changeIndex++;
        }
        changeData.setData(Arrays.asList(changeDataList));
        excelDataList.add(changeData);

        // 子项变更列表
        List<MaterialResumeChangeDto> childChangeList = (List<MaterialResumeChangeDto>) menuMap.get("childChangeList");
        ExcelData childChangeData = new ExcelData();
        childChangeData.setFileName("子项变更列表");
        String[] childChangeHead = {"序号", "变更内容", "物料号", "描述", "参考号", "T", "生效日期", "失效日期", "有替换", "版本", "ECN号", "域"};
        childChangeData.setHead(childChangeHead);
        String[][] childDataList = new String[childChangeList.size()][childChangeHead.length];
        int childIndex = 0;
        for (MaterialResumeChangeDto item : childChangeList) {
            childDataList[childIndex][0] = String.valueOf(childIndex + 1);
            childDataList[childIndex][1] = item.getChangingCategory();
            childDataList[childIndex][2] = item.getMaterialNo();
            childDataList[childIndex][3] = item.getDesc();
            childDataList[childIndex][4] = item.getRefNumber();
            childDataList[childIndex][5] = item.getPsCode();
            childDataList[childIndex][6] = item.getStartTime();

            childDataList[childIndex][7] = item.getEndTime();
            childDataList[childIndex][8] = item.getReplace();
            childDataList[childIndex][9] = item.getVersion();
            childDataList[childIndex][10] = item.getEcnNo();
            childDataList[childIndex][11] = item.getRegion();
            childIndex++;
        }
        childChangeData.setData(Arrays.asList(childDataList));
        excelDataList.add(childChangeData);

        ExcelUtils.exportExcel(response, excelDataList, "物料履历导出excel.xlsx");
    }

    private List<String> getFirstChildMaterial(String material, String region, String startTime) {
        List<String> firstList = new ArrayList<>();
        firstList.add(material);
        List<MaterialInfoDto> materialInfoDtoList = syncService.getChildMaterials(firstList, region, startTime);
        List<String> currents = new ArrayList<>(materialInfoDtoList.size());
        if (materialInfoDtoList.size() > 0) {
            currents = materialInfoDtoList.stream().map(MaterialInfoDto::getChildMaterial).collect(Collectors.toList());
        }
        return currents;
    }

    /**
     * 获取全部子项
     *
     * @param currentMaterial 当前物料号
     * @param region          所属域
     * @param materialList    子项物料号列表
     * @param startTime       子项起始时间
     * @return 子项物料号列表
     */
    private List<String> getChildMaterial(List<String> currentMaterial, String region, List<String> materialList, String startTime) {
        if (currentMaterial.isEmpty()) {
            return new ArrayList<>();
        }
        List<MaterialInfoDto> materialInfoDtoList = syncService.getChildMaterials(currentMaterial, region, startTime);
        if (materialInfoDtoList.size() > 0) {
            List<String> currents = materialInfoDtoList.stream().map(MaterialInfoDto::getChildMaterial).collect(Collectors.toList());
            materialList.addAll(currents);
            materialList = getChildMaterial(currents, region, materialList, startTime);
        }
        return materialList;
    }

    /**
     * 查询子项全部变更记录
     *
     * @param firstChildList 首层子项列表
     * @param childList      子项列表
     * @param material       父项物料
     * @param region         所属域
     * @param childStartTime 记录起始时间
     * @return 子项全部变更记录
     */
    private List<MaterialResumeChangeDto> queryChildChange(List<String> firstChildList, List<String> childList, String material, String region, String childStartTime) {

        List<MaterialResumeChangeDto> recordList = new ArrayList<>();
        if (firstChildList.size() == 0) {
            return recordList;
        }
        // ecn变更信息
        List<EcnContent> ecnContentList = new ArrayList<>();
        // ecn变更信息
        List<EcnContent> ecnFirstContentList = new ArrayList<>();
        if (firstChildList.size() > 0) {
            ecnFirstContentList = outEcnService.getEcnContentByIds(firstChildList, material, null, region, childStartTime);
        }
        List<EcnContent> ecnChildContentList = new ArrayList<>();
        if (!ObjectUtils.isEmpty(childList)) {
            List<String> parentList = new ArrayList<>();
            parentList.addAll(firstChildList);
            parentList.addAll(childList);
            // ecn变更信息
            int total = childList.size();
            if (total > 100) {
                int maxInt = (int) Math.ceil(total / 100);
                for (int i = 0; i < maxInt; i++) {
                    int startNum = 100 * i;
                    List<String> subChildList = childList.subList(startNum, Math.min(startNum + 100,total-1));
                    List<EcnContent> subEcnChildContentList = outEcnService.getEcnContentByIds(subChildList, null, parentList, region, childStartTime);
                    if (!ObjectUtils.isEmpty(subEcnChildContentList)) {
                        ecnChildContentList.addAll(subEcnChildContentList);
                    }
                }
            } else {
                ecnChildContentList = outEcnService.getEcnContentByIds(childList, null, parentList, region, childStartTime);
            }
        }

        ecnContentList.addAll(ecnFirstContentList);
        ecnContentList.addAll(ecnChildContentList);
        Map<String, String> contentExistMap = new HashMap<>();
        for (EcnContent content : ecnContentList) {
            String key = content.getEcnNo() + content.getChangingCategory() + content.getStartTime() + content.getEndTime();
            if (contentExistMap.containsKey(key)) {
                continue;
            }
            contentExistMap.put(key, key);

            MaterialResumeChangeDto resumeChangeDto = new MaterialResumeChangeDto();
            resumeChangeDto.setMaterialNo(content.getMaterialNo());
            resumeChangeDto.setRegion(content.getRegion());
            resumeChangeDto.setVersion(content.getRev());
            resumeChangeDto.setDesc(content.getDesc1());
            resumeChangeDto.setRefNumber(content.getRef());
            resumeChangeDto.setPsCode(content.getPsCode());
            String startTime = StringUtils.isNotEmpty(content.getStartTime()) ?
                    TimeUtils.formatTime(content.getStartTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD) : null;
            resumeChangeDto.setStartTime(StringUtils.equals(startTime, "1900-01-01") ? null : startTime);
            String endTime = StringUtils.isNotEmpty(content.getEndTime()) ?
                    TimeUtils.formatTime(content.getEndTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS_s, TimeFormatConstants.YYYY_MM_DD) : null;
            resumeChangeDto.setEndTime(StringUtils.equals(endTime, "1900-01-01") ? null : endTime);
            resumeChangeDto.setCompareTime(StringUtils.isNotEmpty(resumeChangeDto.getStartTime()) ? resumeChangeDto.getStartTime() : resumeChangeDto.getEndTime());
            resumeChangeDto.setChangingCategory(ChangeCategoryTypeEnum.getNameByValue(ChangeCategoryTypeEnum.getValueByCategory(content.getChangingCategory())));
            resumeChangeDto.setOperateTypeName(MaterialResumeTypeEnum.ECN_CHANGE.getName());
            resumeChangeDto.setEcnNo(content.getEcnNo());
//            if (StringUtils.equals(content.getChangingCategory(), ChangeCategoryTypeEnum.EXP_BOM.getCategory()) && !StringUtils.isEmpty(mrReplace.getId())) {
//                MaterialReplace mr = materialReplaceDao.selectById(mrReplace.getSourceId());
//                resumeChangeDto.setReplace(mr.getReplaceMaterial());
//            }
            if (StringUtils.equals(content.getChangingCategory(), ChangeCategoryTypeEnum.NEW_BOM.getCategory())) {
                continue;
            }
            recordList.add(resumeChangeDto);
        }

        if (!ObjectUtils.isEmpty(childList)) {
            List<MaterialResumeChangeDto> mocDetailList = mocDetailDao.getDetailsByChildMaterial(childList, region);
            for (MaterialResumeChangeDto mocDetail : mocDetailList) {
                mocDetail.setStartTime(StringUtils.isNotEmpty(mocDetail.getStartTime()) ?
                        TimeUtils.formatTime(mocDetail.getStartTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS, TimeFormatConstants.YYYY_MM_DD)
                        : null);
                mocDetail.setEndTime(StringUtils.isNotEmpty(mocDetail.getEndTime()) ?
                        TimeUtils.formatTime(mocDetail.getEndTime(), TimeFormatConstants.YYYY_MM_DD_HH_MM_SS, TimeFormatConstants.YYYY_MM_DD)
                        : null);
                mocDetail.setOperateTypeName(MaterialResumeTypeEnum.getNameByValue(mocDetail.getOperateType()));
                recordList.add(mocDetail);
            }
        }

        // 二次排序
        List<MaterialResumeChangeDto> changeList;
        List<MaterialResumeChangeDto> changeResultList = new ArrayList<>(recordList.size());
        if (recordList.size() > 0) {
            changeList = recordList.stream().sorted(
                    Comparator.nullsLast(Comparator.comparing(MaterialResumeChangeDto::getCompareTime,
                            Comparator.nullsLast(String::compareTo)))).collect(Collectors.toList());
            int sort = 1;
            for (MaterialResumeChangeDto mr : changeList) {
                mr.setSort(sort);

                changeResultList.add(mr);
                sort++;
            }
        }
        return changeResultList;
    }

    /**
     * 查询子项变更履历
     *
     * @param childChangeList 子项变更记录
     * @return 子项变更履历
     */
    private List<MaterialResume> queryChildResume(List<MaterialResumeChangeDto> childChangeList) {
        List<MaterialResume> childMrList = new ArrayList<>();
        if (childChangeList.size() == 0) {
            return childMrList;
        }
        for (MaterialResumeChangeDto dto : childChangeList) {
            if (StringUtils.isEmpty(dto.getCompareTime())) {
                continue;
            }
            MaterialResume mr = new MaterialResume();
            mr.setOperateTime(dto.getCompareTime());
            mr.setMaterialNo(dto.getMaterialNo());
            mr.setContent(dto.getChangingCategory());
            childMrList.add(mr);
        }
        return childMrList.stream().sorted(
                Comparator.nullsLast(Comparator.comparing(MaterialResume::getOperateTime,
                        Comparator.nullsLast(String::compareTo)))).collect(Collectors.toList());
    }

}
